import { Request, Response, NextFunction } from 'express';
import logger from '@utils/logger';
import Alert from '@database/models/Alert';
import Ticket from '@database/models/Ticket';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime'

dayjs.extend(relativeTime);

/**
 * Dashboard 控制器
 */
class DashboardController {
  /**
   * 获取 Dashboard 概览数据
   */
  async getOverview(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const now = new Date();
      const yesterday = dayjs().subtract(1, 'day').toDate();
      const yesterdayStart = dayjs().subtract(2, 'day').toDate();

      // 获取今日工单数
      const todayTickets = await Ticket.countDocuments({
        createdAt: { $gte: dayjs().startOf('day').toDate() }
      });

      const yesterdayTickets = await Ticket.countDocuments({
        createdAt: { $gte: dayjs().subtract(1, 'day').startOf('day').toDate(), $lt: dayjs().startOf('day').toDate() }
      });

      const ticketsTrend = yesterdayTickets > 0
        ? Math.round(((todayTickets - yesterdayTickets) / yesterdayTickets) * 100)
        : 0;

      // 获取活跃告警数
      const activeAlerts = await Alert.countDocuments({
        status: 'firing'
      });

      const yesterdayActiveAlerts = await Alert.countDocuments({
        status: 'firing',
        createdAt: { $gte: yesterdayStart, $lt: yesterday }
      });

      const alertsTrend = yesterdayActiveAlerts > 0
        ? Math.round(((activeAlerts - yesterdayActiveAlerts) / yesterdayActiveAlerts) * 100)
        : 0;

      // 计算解决率
      const totalTickets = await Ticket.countDocuments();
      const resolvedTickets = await Ticket.countDocuments({
        status: { $in: ['resolved', 'closed'] }
      });

      const resolutionRate = totalTickets > 0
        ? Math.round((resolvedTickets / totalTickets) * 100)
        : 0;

      // 计算平均响应时间（分钟）
      const recentResolvedTickets = await Ticket.find({
        status: { $in: ['resolved', 'closed'] },
        'resolution.resolvedAt': { $gte: dayjs().subtract(7, 'days').toDate() }
      }).limit(100);

      let totalResponseTime = 0;
      recentResolvedTickets.forEach(ticket => {
        if (ticket.resolution?.resolvedAt) {
          const responseTime = dayjs(ticket.resolution.resolvedAt).diff(dayjs(ticket.createdAt), 'minute');
          totalResponseTime += responseTime;
        }
      });

      const avgResponse = recentResolvedTickets.length > 0
        ? Math.round(totalResponseTime / recentResolvedTickets.length)
        : 0;

      res.status(200).json({
        success: true,
        data: {
          stats: [
            {
              title: 'Open Tickets',
              value: todayTickets,
              suffix: '',
              color: '#52c41a',
              type: 'success',
              gradient: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
              trend: ticketsTrend
            },
            {
              title: 'Active Alerts',
              value: activeAlerts,
              suffix: '',
              color: '#ff4d4f',
              type: 'danger',
              gradient: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
              trend: alertsTrend
            },
            {
              title: 'Resolution Rate',
              value: resolutionRate,
              suffix: '%',
              color: '#1890ff',
              type: 'info',
              gradient: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
              trend: 8
            },
            {
              title: 'Avg Response',
              value: avgResponse,
              suffix: 'min',
              color: '#722ed1',
              type: 'warning',
              gradient: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
              trend: -15
            }
          ]
        }
      });
    } catch (error) {
      logger.error('Failed to get dashboard overview:', error as Error);
      next(error);
    }
  }

  /**
   * 获取最近告警
   */
  async getRecentAlerts(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const limit = parseInt(req.query.limit as string) || 5;

      const alerts = await Alert.find()
        .sort({ createdAt: -1 })
        .limit(limit);

      const formattedAlerts = alerts.map(alert => ({
        title: (alert as any).name || alert.labels?.alertname || 'Unknown Alert',
        severity: alert.severity === 'critical' ? 'error' : alert.severity,
        time: dayjs(alert.createdAt).fromNow()
      }));

      res.status(200).json({
        success: true,
        data: formattedAlerts
      });
    } catch (error) {
      logger.error('Failed to get recent alerts:', error as Error);
      next(error);
    }
  }

  /**
   * 获取服务状态
   */
  async getServicesStatus(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { performHealthCheck } = await import('@utils/healthCheck');
      const health = await performHealthCheck();

      const services = [
        {
          name: 'MongoDB',
          status: health.checks.database.status === 'pass' ? 'healthy' : 'error',
          responseTime: health.checks.database.responseTime || 0
        },
        {
          name: 'Redis',
          status: health.checks.redis.status === 'pass' ? 'healthy' :
                  health.checks.redis.status === 'warn' ? 'degraded' : 'error',
          responseTime: health.checks.redis.responseTime || 0
        },
        {
          name: 'API Gateway',
          status: 'healthy',
          responseTime: Math.floor(Math.random() * 30) + 10
        },
        {
          name: 'Memory',
          status: health.checks.memory.status === 'pass' ? 'healthy' :
                  health.checks.memory.status === 'warn' ? 'degraded' : 'error',
          responseTime: 0
        }
      ];

      res.status(200).json({
        success: true,
        data: services
      });
    } catch (error) {
      logger.error('Failed to get services status:', error as Error);
      next(error);
    }
  }

  /**
   * Get performance metrics
   */
  async getPerformanceMetrics(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const hours = parseInt(req.query.hours as string) || 24;

      // Try to get real metrics from Prometheus
      const prometheusService = await import('@services/prometheus.service');
      const metrics = await prometheusService.default.getAllMetrics(hours);

      res.status(200).json({
        success: true,
        data: metrics
      });
    } catch (error) {
      logger.error('Failed to get performance metrics:', error as Error);
      next(error);
    }
  }
}

export default new DashboardController();
